﻿using System;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;

namespace Vcm
{
    public struct Arguments
    {
        public string InputFileName;
        public string OutputFileName;
        public char CsvDelimiter;
        public string ArtPath;
        public string Copyright;
        public string Watermark;
        public CardPosition WatermarkPosition;
        public TextOrientation WatermarkOrientation;
        public int WatermarkColor;
        public int WatermarkOpacity;
        public string ExpansionSetSymbolPath;
        public bool UseGhost;
        public bool NotForLegalPlay;
        public int CardsPerPage;
    }

    class Program
    {
        static void Main(string[] args)
        {
            Arguments arguments;

            if (!TryGetArguments(args, out arguments))
            {
                WriteUsage();
                return;
            }

            var data = DataImport.ImportCsv(arguments.InputFileName, arguments.CsvDelimiter, true);

            //var expansionSetSymbolPath = @"c:\SVN\Ankha-VCM2\Ankha-VCM-GUI\bin\Release\expansion.gif";

            var doc = ProxyDocument.CreateProxiesPdf(arguments.OutputFileName, arguments.ArtPath, arguments.Copyright, arguments.Watermark, arguments.WatermarkPosition, arguments.WatermarkOrientation, arguments.WatermarkColor, arguments.WatermarkOpacity, arguments.ExpansionSetSymbolPath, arguments.UseGhost, arguments.NotForLegalPlay, arguments.CardsPerPage);

            try
            {
                ICardMaker cardMaker = null;
                foreach (DataRow row in data.Rows)
                {
                    if (row.ItemArray.All(item => item.ToString().Trim().Length == 0)) // skip empty lines
                        continue;

                    if (cardMaker == null)
                    {
                        cardMaker = new LibraryCardMaker();
                        if (!cardMaker.SupportsRow(row))
                        {
                            cardMaker = new CryptCardMaker();
                            if (!cardMaker.SupportsRow(row))
                                throw new Exception("Row format is not supported. Check that the columns are correct.");
                        }
                    }

                    // TO FIX (later): Lucky Blow (textbox too narrow), IR Goggles (line length varies too much)

                    //if (!row["name"].ToString().StartsWith("emergency", StringComparison.InvariantCultureIgnoreCase))
                    //    continue;
                    //if (!row["name"].ToString().Equals("Aisling Sturbridge", StringComparison.InvariantCultureIgnoreCase))
                    //if (!row["name"].ToString().StartsWith("Angus", StringComparison.InvariantCultureIgnoreCase))
                    //continue;
                    //if (row["type"].ToString() != "Action modifier")
                    //if (row["Pool cost"].ToString() == "")
                    //    continue;
                    //row["name"] = "New Carthage";
                    string message;
                    cardMaker.AddCard(doc, row, out message);
                    Console.WriteLine(message);
                    //break;
                }
                if (cardMaker != null)
                    cardMaker.DrawCutLines(doc);
            }
            catch
            {
                if (doc != null)
                    ProxyDocument.EnsureDocumentCanBeClosed(doc);
                throw;
            }
            finally
            {
                ProxyDocument.SaveAndCloseProxiesPdf(doc);
            }
        }

        private static bool TryGetArguments(string[] args, out Arguments arguments)
        {
            arguments = new Arguments();
            if (args.Length < 2 || args.Length > 20)
                return false;

            // default values
            arguments.InputFileName = args[0];
            arguments.OutputFileName = args[1];
            arguments.CsvDelimiter = ',';
            arguments.ArtPath = ".";
            arguments.Copyright = "(C)2011 CCP hf. All Rights Reserved.";
            arguments.Watermark = "CONFIDENTIAL PROPERTY OF VEKN";
            arguments.WatermarkOrientation = TextOrientation.Oblique;
            arguments.WatermarkPosition = CardPosition.ArtBox;
            arguments.WatermarkColor = 0;
            arguments.WatermarkOpacity = 80;
            arguments.ExpansionSetSymbolPath = null;
            arguments.UseGhost = false;
            arguments.NotForLegalPlay = false;
            arguments.CardsPerPage = 9;

            if (args.Length == 2)
                return true;

            // get arguments
            for (int i = 2; i < args.Length; ++i)
            {
                switch (args[i])
                {
                    case "-delimiter":
                        if (i == args.Length - 1)
                            return false;
                        if (args[i + 1].Length != 1)
                            return false;
                        arguments.CsvDelimiter = args[++i][0];
                        break;
                    case "-artpath":
                        if (i == args.Length - 1)
                            return false;
                        arguments.ArtPath = args[++i];
                        break;
                    case "-copyright":
                        if (i == args.Length - 1)
                            return false;
                        arguments.Copyright = args[++i];
                        break;
                    case "-watermark":
                        if (i == args.Length - 1)
                            return false;
                        arguments.Watermark = args[++i];
                        break;
                    case "-expansion":
                        if (i == args.Length - 1)
                            return false;
                        arguments.ExpansionSetSymbolPath = args[++i];
                        break;
                    case "-ghost":
                        arguments.UseGhost = true;
                        break;
                    case "-notForLegalPlay":
                        arguments.NotForLegalPlay = true;
                        break;
                    case "-cardsPerPage":
                        int cardsPerPage;
                        if (Int32.TryParse(args[++i], out cardsPerPage) && (cardsPerPage == 9 || cardsPerPage == 1))
                            arguments.CardsPerPage = cardsPerPage;
                        break;
                    case "-watermarkposition":
                        CardPosition cardPosition;
                        if (Enum.TryParse(args[++i], out cardPosition))
                            arguments.WatermarkPosition = cardPosition;
                        break;
                    case "-watermarkorientation":
                        TextOrientation orientation;
                        if (Enum.TryParse(args[++i], out orientation))
                            arguments.WatermarkOrientation = orientation;
                        break;
                    case "-watermarkcolor":
                        var color = args[++i];
                        int colorValue;
                        if (color.Length == 7 && color[0] == '#' && int.TryParse(color.Substring(1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out colorValue))
                            arguments.WatermarkColor = colorValue;
                        break;
                    case "-watermarkopacity":
                        int opacity;
                        if (Int32.TryParse(args[++i], out opacity) && opacity >= 0 && opacity <= 100)
                            arguments.WatermarkOpacity = opacity;
                        break;
                    default:
                        return false;
                }
            }
            return true;
        }

        private static void WriteUsage()
        {
            Console.WriteLine("Invalid arguments.");
            Console.WriteLine("Expected arguments: <filename>.csv <outputname>.pdf [-delimiter <csv column delimiter>] [-artpath <path to art>] [-copyright <copyright text>] [-expansion <expansion symbol path>.gif|.png] [-watermark <watermark>] [-watermarkposition ArtBox|TextBox] [-watermarkorientation Horizontal|Oblique] [-watermarkcolor #RRGGBB] [-watermarkopacity 0-100] [-ghost] [-notForLegalPlay] [-cardsPerPage 1|9]");
            Console.WriteLine("The default column delimiter is: ,");
            Console.WriteLine("If using art path, the name of the art image must be the name of the card,"
                + " with the following characters replaced by underscores ( _ ):    "
                + String.Join(" ", Path.GetInvalidFileNameChars().Where(c => ((byte)c) > 32)));
        }
    }
}
